/*
 * frame.java
 *
 * Created on 24. duben 2009, 15:55
 */
package orderingtasks;

import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.Stack;
import java.util.StringTokenizer;

/**
 *
 * @author  Duke
 */
public class frame extends javax.swing.JFrame {

    /** Creates new form frame */
    public frame() {
        initComponents();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();
        jScrollPane1 = new javax.swing.JScrollPane();
        input = new javax.swing.JTextArea();
        jLabel2 = new javax.swing.JLabel();
        execute = new javax.swing.JButton();
        output = new javax.swing.JTextField();
        jMenuBar1 = new javax.swing.JMenuBar();
        jMenu1 = new javax.swing.JMenu();
        open = new javax.swing.JMenuItem();
        save = new javax.swing.JMenuItem();
        exit = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jLabel1.setText("Input:");

        input.setColumns(8);
        input.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        input.setRows(5);
        jScrollPane1.setViewportView(input);

        jLabel2.setText("Output:");

        execute.setText("Go");
        execute.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                executeActionPerformed(evt);
            }
        });

        output.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N

        jMenu1.setText("File");

        open.setText("Open");
        jMenu1.add(open);

        save.setText("Save");
        jMenu1.add(save);

        exit.setText("Exit");
        jMenu1.add(exit);

        jMenuBar1.add(jMenu1);

        setJMenuBar(jMenuBar1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel1)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 87, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(execute)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(output, javax.swing.GroupLayout.PREFERRED_SIZE, 161, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel2))
                .addContainerGap(95, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(jLabel2))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(execute)
                        .addComponent(output, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 187, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(129, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

private void executeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_executeActionPerformed
    orderTask();
}//GEN-LAST:event_executeActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new frame().setVisible(true);
            }
        });
    }

    private String[] getTextAreaArray() {
        String in = input.getText();
        String[] str = in.split("\n");
        /* System.out.println("strlen: " + str.length);
        for (int i = 0; i < str.length; i++) {
        System.out.println("str: " + str[i]);
        }*/
        return str;
    }

    private static boolean checkInput(String str) {
        if (str.matches("^\\d+\\s+\\d+$")) {
            return true;
        } else {
            return false;
        }
    }

    private static int[] splitInput(String str) {
        int pole[] = new int[2];
        StringTokenizer st = new StringTokenizer(str);
        pole[0] = Integer.parseInt(st.nextToken());
        pole[1] = Integer.parseInt(st.nextToken());
        return pole;
    }

    private void orderTask() {
        Graf gr = new Graf();
        int ukolu, zavislosti;
        String str[] = getTextAreaArray();
        if (checkInput(str[0])) {
            ukolu = splitInput(str[0])[0];
            zavislosti = splitInput(str[0])[1];
            //System.out.println("ukolu: " + ukolu + " zavislosti: " + zavislosti);
            for (int i = 0; i < ukolu; i++) {
                gr.pridejUzel(new Uzel(i + 1));
            }
            for (int i = 1; i < zavislosti + 1; i++) {
                System.out.println("nastavuju uzlu: " + splitInput(str[i])[0] + " naslednika: " + splitInput(str[i])[1]);
                //gr.graf.get(splitInput(str[i])[0] - 1).pridejNaslednika(gr.graf.get(splitInput(str[i])[1] - 1));
            //gr.setUzelNaslednik(splitInput(str[i])[0], splitInput(str[0])[1]);
                gr.addUzelNaslednik(splitInput(str[i])[0], splitInput(str[i])[1]);
            }
            gr.DFS();
            output.setText(gr.DFSShow());
        }
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    public javax.swing.JButton execute;
    public javax.swing.JMenuItem exit;
    public javax.swing.JTextArea input;
    public javax.swing.JLabel jLabel1;
    public javax.swing.JLabel jLabel2;
    public javax.swing.JMenu jMenu1;
    public javax.swing.JMenuBar jMenuBar1;
    public javax.swing.JScrollPane jScrollPane1;
    public javax.swing.JMenuItem open;
    public javax.swing.JTextField output;
    public javax.swing.JMenuItem save;
    // End of variables declaration//GEN-END:variables
}

class Graf {

    public static final int FRESH = 0,  OPEN = 1,  CLOSE = 2;
    private List<Uzel> graf = new LinkedList();
    int cas;
    Stack<Uzel> stack = new Stack<Uzel>();

    public void pridejUzel(Uzel uzel) {
        graf.add(uzel);
    }

    public Uzel getUzel(int index) {
        return graf.get(index - 1);
    }

    public void addUzelNaslednik(int index, int nasl) {
        //System.out.println("uzel: " + graf.get(index - 1).getData());
        graf.get(index - 1).pridejNaslednika(graf.get(nasl - 1));
    //System.out.println("nasl: " + graf.get(index - 1).naslednici.size());
    }

    public void pridejHranu(Uzel start, Uzel end) {
        start.pridejNaslednika(end);
    }

    public void show() {
        System.out.println("Obsah grafu:");
        Iterator it = graf.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
    }

    public void DFS() {
        cas = 0;
        Iterator<Uzel> it = graf.iterator();
        while (it.hasNext()) {
            Uzel u = it.next();
            if (u.getStav() == FRESH) {
                DFSGo(u);
            }
        }
    }

    public void DFSGo(Uzel u) {
        u.setStav(OPEN);
        cas++;
        u.setCas(cas);
        Iterator<Uzel> it = u.naslednici.iterator();
        while (it.hasNext()) {
            Uzel uu = it.next();
            if (uu.getStav() == FRESH) {
                uu.setPredchudce(u);
                DFSGo(uu);
            }
        }
        u.setStav(CLOSE);
        //stack.add(u);
        stack.push(u);
        cas++;
        u.setVzdalenost(cas);
    }

    public String DFSShow() {
        String str = "";
        Iterator<Uzel> it = stack.iterator();
        int pole[] = new int[stack.size()];
        int count = 0;
        while (it.hasNext()) {
            str += " " + it.next().getData();
        //System.out.print(" " + it.next().getData());
        }
        return str;
    }
}

class Uzel<Integer> { //pole uzlu


    public static final  int FRESH = 0,  OPEN = 1,  CLOSE = 2;
    private int data;
    private  int stav = FRESH,  cas = 0,  vzdalenost = 0;
    public Set<Uzel> naslednici = new LinkedHashSet<Uzel>();//List,ArrayList
    public Uzel predchudce;//List,ArrayList

    public Uzel(int data) {
        this.data = data;
    }

    public void pridejNaslednika(Uzel uzel) {
        naslednici.add(uzel);
    }

    public void setPredchudce(Uzel uzel) {
        this.predchudce = uzel;
    }

    public int getData() {
        return data;
    }

    public void setStav(int stav) {
        this.stav = stav;
    }

    public int getStav() {
        return stav;
    }

    public void setCas(int cas) {
        this.cas = cas;
    }

    public void setVzdalenost(int vzdalenost) {
        this.vzdalenost = vzdalenost;
    }

    public String getNasledniky() {
        if (naslednici.isEmpty()) {
            return "";
        }
        String str = " Naslednici: ";
        Iterator it = naslednici.iterator();
        while (it.hasNext()) {
            str += " " + it.next().toString();
        }
        return str;
    }

    /*public String toString() {
    String naslednik = "Uzel " + data + this.getNasledniky();
    return naslednik;
    }*/
}
